package com.opensso.client.ctrl;


import com.opensso.core.entity.BeanRet;
import com.opensso.core.enums.SessionEnum;
import com.opensso.core.exceptions.BaseException;
import com.opensso.core.tools.JwtToken;
import com.opensso.domain.entity.DomainPool;
import com.opensso.domain.service.DomainPoolSV;
import com.opensso.sessioin.service.SessionSV;
import com.opensso.setting.entity.Setting;
import com.opensso.setting.service.SettingSV;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/token")
@Slf4j
@Api(value = "验证控制器", description = "验证控制器")
public class TokenCtrl {

    @Resource
    private DomainPoolSV domainPoolSV;

    @Resource
    private SessionSV sessionSV;

    @Resource
    private SettingSV settingSV;

    /**
     * 刷新token
     *
     * @param token  登录的token
     * @param apiKey apiKey
     * @return BeanRet
     */
    @ApiOperation(value = "刷新token", notes = "刷新token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ApiKey", value = "apikey", dataType = "java.lang.String", paramType = "query")
    })
    @PostMapping("/refresh/timeout")
    @ResponseBody
    public BeanRet refreshTokenTimeout(@RequestParam("Token") String token, @RequestParam("ApiKey") String apiKey, HttpServletRequest request) {
        if (StringUtils.isBlank(apiKey)) {
            return BeanRet.create();
        }

        DomainPool domainPool = domainPoolSV.loadByApiKey(apiKey);
        if (domainPool == null) {
            return BeanRet.create();
        }

        boolean flag = JwtToken.verifier(token, domainPool.getApiSecret());
        if (!flag) {
            return BeanRet.create();
        }

        String serverIp = request.getServerName();
        String requestUrl = request.getRequestURI();
        String account = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.Account.name());
        String clientIp = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.ClientIp.name());
        String language = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.Language.name());
        String sesionKey = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.SessionKey.name());
        String tokenNew = sessionSV.refresh(account, sesionKey, clientIp, serverIp, language, requestUrl, apiKey);
        return BeanRet.create(true, "", (Object) tokenNew);
    }


    /**
     * 刷新token
     *
     * @param token  登录的token
     * @param apiKey apiKey
     * @return BeanRet
     */
    @ApiOperation(value = "刷新token", notes = "刷新token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ApiKey", value = "apikey", dataType = "java.lang.String", paramType = "query")
    })
    @PostMapping("/refresh")
    @ResponseBody
    public BeanRet refreshToken(@RequestParam("Token") String token, @RequestParam("ApiKey") String apiKey, HttpServletRequest request) {
        if (StringUtils.isBlank(apiKey)) {
            return BeanRet.create();
        }

        DomainPool domainPool = domainPoolSV.loadByApiKey(apiKey);
        if (domainPool == null) {
            return BeanRet.create();
        }

        String token_Secret = settingSV.loadByK(Setting.Key.Token_Secret);//refresh_token过期时间

        boolean flag = JwtToken.verifier(token, token_Secret);
        if (!flag) {
            return BeanRet.create();
        }

        String serverIp = request.getServerName();
        String requestUrl = request.getRequestURI();
        String refreshToken = JwtToken.getTokenValue(token, token_Secret, SessionEnum.RefreshToken.name());
        if (!SessionEnum.RefreshToken.name().equals(refreshToken)) {
            return BeanRet.create();
        }
        String account = JwtToken.getTokenValue(token, token_Secret, SessionEnum.Account.name());
        String clientIp = JwtToken.getTokenValue(token, token_Secret, SessionEnum.ClientIp.name());
        String language = JwtToken.getTokenValue(token, token_Secret, SessionEnum.Language.name());
        String sesionKey = JwtToken.getTokenValue(token, token_Secret, SessionEnum.SessionKey.name());
        String tokenNew = sessionSV.refresh(account, sesionKey, clientIp, serverIp, language, requestUrl, apiKey);
        return BeanRet.create(true, "", (Object) tokenNew);
    }


    /**
     * 注销登录
     *
     * @param token  登录的token
     * @param apiKey apiKey
     * @return BeanRet
     */
    @ApiOperation(value = "注销登录", notes = "注销登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ApiKey", value = "apikey", dataType = "java.lang.String", paramType = "query")
    })
    @PostMapping("/invalidate")
    @ResponseBody
    public BeanRet invalidate(@RequestParam("Token") String token, @RequestParam("ApiKey") String apiKey, HttpServletRequest request) {

        if (StringUtils.isBlank(apiKey)) {
            return BeanRet.create();
        }

        DomainPool domainPool = domainPoolSV.loadByApiKey(apiKey);
        if (domainPool == null) {
            return BeanRet.create();
        }

        boolean flag = JwtToken.verifier(token, domainPool.getApiSecret());
        if (!flag) {
            return BeanRet.create();
        }


        String serverIp = request.getServerName();
        String requestUrl = request.getRequestURI();
        String account = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.Account.name());
        String clientIp = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.ClientIp.name());
        String language = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.Language.name());
        String sesionKey = JwtToken.getTokenValue(token, domainPool.getApiSecret(), SessionEnum.SessionKey.name());
        boolean isInvalidate = sessionSV.invalidate(account, sesionKey, clientIp, serverIp, language, requestUrl, apiKey);
        if (isInvalidate) {
            return BeanRet.create(true, BaseException.BaseExceptionEnum.Success);
        }

        return BeanRet.create(true, BaseException.BaseExceptionEnum.Session_Invalidate_Error);
    }


}
